package com.saxon.system.utils;


import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.saxon.system.pojo.SysAuthUser;
import io.swagger.annotations.ApiModelProperty;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * jwt工具类
 *
 * @author 莫松
 */
@Component
public class JwtTokenUtil {
    @ApiModelProperty ("JWT密钥")
    @Value ("${jwt.secret-key}")
    private String secret;
    @ApiModelProperty ("JWT过期时间")
    @Value ("${jwt.expiration-time}")
    private Long expiration;
    @Autowired
    RedisUtil redisUtil;

    /**
     * 根据负责生成JWT的token
     */
    public String generateToken (String jwtId, Map<String, String> claims) {
        JWTCreator.Builder builder = JWT.create ();
        //设置jwt的id
        builder.withJWTId (jwtId);
        //设置属性
        claims.forEach ((k, v) -> builder.withClaim (k, v));
        //设置过期时间
        builder.withExpiresAt (new Date (System.currentTimeMillis () + expiration));
        //设置算法
        String token = builder.sign (Algorithm.HMAC256 (secret));
        return token;
    }

    /**
     * 获得用户名
     *
     * @param authToken token
     * @return 返回用户名
     */
    public String getUsernameFromToken (String authToken) {
        DecodedJWT verify = JWT.require (Algorithm.HMAC256 (secret)).build ().verify (authToken);
        return verify.getClaim ("username").asString ();
    }

    /**
     * 解析token
     */
    public Map<String, Object> getClaimsFromToken (String token) {
        Map<String, Object> map = new HashMap<> (2);
        try {
            JWT.require (Algorithm.HMAC256 (secret)).build ().verify (token);
            map.put ("state", true);
            map.put ("msg", "认证成功");
        } catch (JWTVerificationException e) {
            map.put ("state", false);
            map.put ("msg", "认证失败");
        }
        return map;
    }

    /**
     * 验证token
     *
     * @param token       token
     * @param userDetails 用户查询
     * @return
     */
    public Boolean validateToken (String token, UserDetails userDetails) {
        SysAuthUser user = (SysAuthUser) userDetails;
        final String username = getUsernameFromToken (token);
        return (
                username.equals (user.getUsername ())
        );
    }


}
